﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Infrastructure.Model.DI;
using Microsoft.Extensions.Logging;
using Model;
using Model.CommonModel.PageModel;
using Model.EntityModel.Auth;
using Model.EntityModel.SysModel;
using Model.QueryModel.system;
using Model.ResultModel;
using Repository.IRepository;
using Repository.IRepository.ISysRepository;
using SqlSugar;

namespace Repository.Repository.SysRepository
{
    [AppService(ServiceType = typeof(IUserRepository), ServiceLifetime = LifeTime.Transient)]
    public class UserRepository : SqlSugarBaseRepository<User>, IUserRepository
    {
        private readonly ILogger<UserRepository> _logger;

        public UserRepository(ILogger<UserRepository> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 根据用户ID获取用户信息
        /// </summary>
        /// <param name="userId">用户唯一标识</param>
        /// <returns>用户实体</returns>
        public User GetUserById(string userId)
        {
            try
            {
                return _db.Queryable<User>()
                    .Where(u => u.UserId == userId)
                    .First();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取用户信息失败，用户ID: {userId}");
                throw new Exception("获取用户信息时发生错误", ex);
            }
        }

        /// <summary>
        /// 根据用户名获取用户信息
        /// </summary>
        /// <param name="username">用户名</param>
        /// <returns>用户实体</returns>
        public User GetUserByUsername(string username)
        {
            try
            {
                return _db.Queryable<User>()
                    .Where(u => u.UserName == username)
                    .First();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取用户信息失败，用户名: {username}");
                throw new Exception("获取用户信息时发生错误", ex);
            }
        }

        /// <summary>
        /// 创建新用户
        /// </summary>
        /// <param name="user">用户实体</param>
        /// <returns>操作结果</returns>
        public bool CreateUser(User user)
        {
            try
            {
                // 设置创建时间
                user.CreatedAt = DateTime.Now;

                return _db.Insertable(user).ExecuteCommand() > 0;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"创建用户失败，用户名: {user.UserName}");
                throw new Exception("创建用户时发生错误", ex);
            }
        }

        /// <summary>
        /// 更新用户信息
        /// </summary>
        /// <param name="user">用户实体</param>
        /// <returns>操作结果</returns>
        public bool UpdateUser(User user)
        {
            try
            {
                // 设置修改时间
                user.ModifiedAt = DateTime.Now;

                return _db.Updateable(user).ExecuteCommand() > 0;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"更新用户信息失败，用户ID: {user.UserId}");
                throw new Exception("更新用户信息时发生错误", ex);
            }
        }

        /// <summary>
        /// 更新用户状态
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="status">新状态(A:激活/I:失效)</param>
        /// <returns>操作结果</returns>
        public bool UpdateUserStatus(string userId, string status)
        {
            try
            {
                return _db.Updateable<User>()
                    .SetColumns(u => new User
                    {
                        Status = status,
                        ModifiedAt = DateTime.Now
                    })
                    .Where(u => u.UserId == userId)
                    .ExecuteCommand() > 0;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"更新用户状态失败，用户ID: {userId}");
                throw new Exception("更新用户状态时发生错误", ex);
            }
        }

        /// <summary>
        /// 更新用户密码
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="newPassword">新密码</param>
        /// <returns>操作结果</returns>
        public bool UpdatePassword(string userId, string newPassword)
        {
            try
            {
                return _db.Updateable<User>()
                    .SetColumns(u => new User
                    {
                        Password = newPassword,
                        PwdStatus = "Y", // 标记为需要修改
                        ModifiedAt = DateTime.Now
                    })
                    .Where(u => u.UserId == userId)
                    .ExecuteCommand() > 0;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"更新用户密码失败，用户ID: {userId}");
                throw new Exception("更新用户密码时发生错误", ex);
            }
        }

        /// <summary>
        /// 获取部门下的所有用户
        /// </summary>
        /// <param name="deptCode">部门编码</param>
        /// <returns>用户列表</returns>
        public List<User> GetUsersByDepartment(string deptCode)
        {
            try
            {
                return _db.Queryable<User>()
                    .Where(u => u.DeptCode == deptCode && u.Status == "A")
                    .ToList();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取部门用户失败，部门编码: {deptCode}");
                throw new Exception("获取部门用户时发生错误", ex);
            }
        }

        public async Task<LoginResult> LoginAsync(string username, string password)
        {
            var user = await _db.Queryable<User>()
                .Where(u => u.UserName == username)
                .FirstAsync();

            if (user == null)
            {
                return new LoginResult { Success = false, Message = "用户名不存在" };
            }

            if (user.Status == "I")
            {
                return new LoginResult
                {
                    Success = false,
                    Message = $"账号已失效{(user.InactiveDate.HasValue ? $"，失效时间：{user.InactiveDate:yyyy-MM-dd}" : "")}"
                };
            }

            if (user.Password != password)
            {
                return new LoginResult { Success = false, Message = "密码错误" };
            }

            return new LoginResult
            {
                Success = true,
                UserId = user.UserId,
                UserName = user.UserName,
                UserRole = user.UserRole,
                DeptCode = user.DeptCode,
                GroupIds = null,
                NeedChangePassword = user.PwdStatus == "Y",
                PwdExpiryDate = user.PwdExpiryDate
            };
        }

        public async Task<bool> ChangePasswordAsync(string userId, string oldPassword, string newPassword)
        {
            var user = await _db.Queryable<User>()
                .Where(u => u.UserId == userId)
                .FirstAsync();

            if (user == null || user.Password != oldPassword)
            {
                return false;
            }

            user.Password = newPassword;
            user.PwdStatus = "N";
            user.PwdExpiryDate = DateTime.Now.AddMonths(3);
            user.ModifiedAt = DateTime.Now;

            return await _db.Updateable(user).ExecuteCommandAsync() > 0;
        }

        public async Task<bool> ResetPasswordAsync(string userId, string newPassword)
        {
            return await _db.Updateable<User>()
                .SetColumns(u => new User
                {
                    Password = newPassword,
                    PwdStatus = "Y",
                    PwdExpiryDate = DateTime.Now.AddDays(7),
                    ModifiedAt = DateTime.Now
                })
                .Where(u => u.UserId == userId)
                .ExecuteCommandAsync() > 0;
        }

        public async Task<List<User>> GetUsersByDeptAsync(string deptCode)
        {
            return await _db.Queryable<User>()
                .Where(u => u.DeptCode == deptCode)
                .ToListAsync();
        }

        public async Task<bool> UpdateUserStatusAsync(string userId, string status, DateTime? inactiveDate = null)
        {
            return await _db.Updateable<User>()
                .SetColumns(u => new User
                {
                    Status = status,
                    InactiveDate = inactiveDate,
                    ModifiedAt = DateTime.Now
                })
                .Where(u => u.UserId == userId)
                .ExecuteCommandAsync() > 0;
        }
        public PagedInfo<User> GetSearch(int pageNum, int pageSize, QueryUser search)
        {
            int totalCount = 0;
            var queryable = _db.Queryable<User>()
                .WhereIF(!string.IsNullOrWhiteSpace(search.UserName), x => x.UserName.Contains(search.UserName))  //用户名模糊查询
                .WhereIF(!string.IsNullOrWhiteSpace(search.UserRole), x => x.UserRole == search.UserRole)
                .WhereIF(!string.IsNullOrWhiteSpace(search.DeptCode), x => x.DeptCode == search.DeptCode)
                .WhereIF(!string.IsNullOrWhiteSpace(search.Status), x => x.Status == search.Status);
            var pages = queryable.ToPageList(pageNum, pageSize, ref totalCount);
            var totalPages = (totalCount - 1) / pageSize + 1;
            return new PagedInfo<User>
            {
                PageIndex = pageNum,
                PageSize = pageSize,
                TotalCount = totalCount,
                Data = pages,
                TotalPage = totalPages
            };
        }

        public bool UserExists(string userId)
        {
            throw new NotImplementedException();
        }
    }
}